/*
 * StartApplication.java
 *
 * Created on October 8, 2006, 12:15 AM
 */

package org.sunspotworld;

import com.sun.spot.core.resources.transducers.ISwitch;
import com.sun.spot.core.resources.transducers.ITriColorLED;
import com.sun.spot.core.resources.transducers.LEDColor;
import com.sun.spot.core.util.Utils;
import com.sun.spot.edemo.EDemoBoard;
import com.sun.spot.ipv6.util.Mutex;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import org.sunspotworld.colorthreads.ColorBlinker;

/**
 * The startApp method of this class is called by the VM to start the
 * application.
 *
 * The manifest specifies this class as MIDlet-1, which means it will
 * be selected for execution.
 */
public class SunSpotApplication extends MIDlet {
    private ITriColorLED [] leds = EDemoBoard.getInstance().getLEDs();
    private ISwitch sw1 = EDemoBoard.getInstance().getSwitches()[0];
    private ISwitch sw2 = EDemoBoard.getInstance().getSwitches()[1];
    private byte demo = 0;

    private boolean[] flashPurple = {true,  true,  true,  false, false, false, false, false};  //blink first 3 leds
    private boolean[] flashTurquo = {false, false, false, true,  true,  true,  false, false};  //blink next 3 leds
    private boolean[] flashYellow = {false, false, false, false, false, false, true,  true};   //last 2

    private ColorBlinker blinkSomePurple     = new ColorBlinker(LEDColor.MAGENTA, flashPurple, 500, 500);
    private ColorBlinker blinkSomeTurquoise  = new ColorBlinker(LEDColor.TURQUOISE, flashTurquo, 300, 300);
    private ColorBlinker blinkSomeYellow     = new ColorBlinker(LEDColor.YELLOW, flashYellow, 275, 525);

    private ColorBlinker blinkAllPurple     = new ColorBlinker(LEDColor.MAGENTA, 500, 500);
    private ColorBlinker blinkAllTurquoise  = new ColorBlinker(LEDColor.TURQUOISE, 300, 300);
    private ColorBlinker blinkAllYellow     = new ColorBlinker(LEDColor.YELLOW, 275, 525);

    private Thread tPurple;
    private Thread tBlueGreen;
    private Thread tYellow;
    private boolean running;

    private Mutex mutex = new Mutex();

    private void respondToSwitches() {
        while (true) {
            Utils.sleep(100);
            if (sw1.isClosed()) {
                running = false;
                try {
                    tPurple.join();
                    tBlueGreen.join();
                    tYellow.join();
                } catch (InterruptedException e) {}
                demo = (byte)((demo + 1)%4);
                switch (demo) {
                    case 0:
                        initialize1();
                        break;
                    case 1:
                        initialize2();
                        break;
                    case 2:
                        initialize3();
                        break;
                    case 3:
                        initialize4();
                        break;

                }
                running = true;
                try {
                    if(!tPurple.isAlive()) {
                        tPurple.start();
                    }
                    if (!tBlueGreen.isAlive()) {
                        tBlueGreen.start();
                    }
                    if (!tYellow.isAlive()) {
                        tYellow.start();
                    }
                } catch (IllegalThreadStateException e) {}
                while(sw1.isClosed()) Utils.sleep(100);
            }
            if (sw2.isClosed()) {

            }
        }
    }

    private void clearColors() {
        for (int i=0; i<leds.length; i++) {
            leds[i].setColor(new LEDColor(0,0,0));
        }
    }

    private void initialize1() {
        clearColors();
        tPurple = new Thread() {
            public void run() {
                while (running) {
                    blinkSomePurple.flash();
                    blinkSomePurple.pauseOff();
                }
            }
        };
        tBlueGreen = new Thread() {
            public void run() {
                while (running) {
                    blinkSomeTurquoise.flash();
                    blinkSomeTurquoise.pauseOff();
                }
            }
        };
        tYellow = new Thread() {
            public void run() {
                while (running) {
                    blinkSomeYellow.flash();
                    blinkSomeYellow.pauseOff();
                }
            }
        };
    }

    private void initialize2() {
        clearColors();
        tPurple = new Thread() {
            public void run() {
                while (running) {
                    blinkAllPurple.flash();
                    blinkAllPurple.pauseOff();
                }
            }
        };
        tBlueGreen = new Thread() {
            public void run() {
                while (running) {
                    blinkAllTurquoise.flash();
                    blinkAllTurquoise.pauseOff();
                }
            }
        };
        tYellow = new Thread() {
            public void run() {
                while (running) {
                    blinkAllYellow.flash();
                    blinkAllYellow.pauseOff();
                }
            }
        };
    }

    private void initialize3() {
        clearColors();
        tPurple = new Thread() {
            public void run() {
                while (running) {
                    synchronized(leds) {
                        blinkAllPurple.flash();
                    }
                    blinkAllPurple.pauseOff();
                }
            }
        };
        tBlueGreen = new Thread() {
            public void run() {
                while (running) {
                    synchronized(leds) {
                        blinkAllTurquoise.flash();
                    }
                    blinkAllTurquoise.pauseOff();
                }
            }
        };
        tYellow = new Thread() {
            public void run() {
                while (running) {
                    synchronized(leds) {
                        blinkAllYellow.flash();
                    }
                    blinkAllYellow.pauseOff();
                }
            }
        };
    }

    private void initialize4() {
        clearColors();
        tPurple = new Thread() {
            public void run() {
                while (running) {
                    mutex.lock();
                    blinkAllPurple.flash();
                    mutex.unlock();
                    blinkAllPurple.pauseOff();
                }
            }
        };
        tBlueGreen = new Thread() {
            public void run() {
                while (running) {
                    mutex.lock();
                    blinkAllTurquoise.flash();
                    mutex.unlock();
                    blinkAllTurquoise.pauseOff();
                }
            }
        };
        tYellow = new Thread() {
            public void run() {
                while (running) {
                    mutex.lock();
                    blinkAllYellow.flash();
                    mutex.unlock();
                    blinkAllYellow.pauseOff();
                }
            }
        };
    }

    protected void startApp() throws MIDletStateChangeException {
        initialize1();
        running = true;
        tPurple.start();
        tBlueGreen.start();
        tYellow.start();
        respondToSwitches();
    }

    protected void pauseApp() {
        // This will never be called by the Squawk VM
    }

    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
        // Only called if startApp throws any exception other than MIDletStateChangeException
    }
}
